/*
 * Copyright 2022-2023 the original author(https://github.com/wj596)
 * 
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * </p>
 */
package org.jsets.fastboot.flowable.component;

import org.apache.ibatis.annotations.Param;
import org.jsets.fastboot.flowable.model.dto.FlowTaskQuery;
import org.jsets.fastboot.flowable.model.entity.FlowTask;
import org.jsets.fastboot.util.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

public class FlowTaskSelectProvider {

	String basic = "select"
			+ "		t.id_ as id,"
			+ "		t.name_ as name,"
			+ "		t.assignee_ as assignee,"
			+ "		t.proc_inst_id_ as proc_inst_id,"
			+ "		t.create_time_ as create_time,"
			+ "		t.due_date_ as due_date,"
			+ "		t.execution_id_ as execution_id,"
			+ "		t.proc_def_id_ as proc_def_id,"
			+ "		t.parent_task_id_ as parent_task_id,"
			+ "		t.task_def_key_ as task_def_key,"
			+ "		t.description_ as description,"
			+ "		t.owner_ as owner,"
			+ "		t.delegation_ as delegation,"
			+ "		t.priority_ as priority,"
			+ "		t.category_ as category,"
			+ "		t.suspension_state_ as suspension_state,"
			+ "		t.tenant_id_ as tenant_id,"
			+ "		t.form_key_ as form_key,"
			+ "		t.claim_time_ as claim_time,"
			+ "		i.start_user_id_ as instance_start_user_id,"
			+ "		i.start_time_ as instance_start_time,"
			+ "		i.business_key_ as business_key,"
			+ "		d.key_ as proc_def_key,"
			+ "		d.name_ as proc_def_name,"
			+ "		d.version_ as proc_def_version,"
			+ "		d.deployment_id_ as deployment_id,"
			+ "		l.user_id_ as candidate,"
			+ "		l.group_id_ as group_id "
			+ "		from"
			+ "		act_ru_task t "
			+ "		join act_ru_execution i on t.proc_inst_id_ = i.id_"
			+ "		join act_re_procdef d on i.proc_def_id_ = d.id_"
			+ "		left join act_ru_identitylink l on l.task_id_ = t.id_ ";
	
	public String getListSql(FlowTaskQuery criteria) {
		StringBuilder sb = new StringBuilder();
		sb.append(basic);
		sb.append(this.createCondition(criteria));
		sb.append("	order by t.create_time_ desc");
		return sb.toString();
	}
	
	public String getPageSql(Page<FlowTask> page, @Param("criteria") FlowTaskQuery criteria) {
		StringBuilder sb = new StringBuilder();
		sb.append(basic);
		sb.append(this.createCondition(criteria));
		sb.append("	order by t.create_time_ desc");
		
	    long startRow = (page.getCurrent() - 1) * page.getSize();
	    long endRow =  startRow+page.getSize();
		return sb.toString();
	}
	
	public String createCondition(FlowTaskQuery criteria) {
		StringBuilder sb = new StringBuilder();
		sb.append("	where 1=1");
		if(StringUtils.notEmpty(criteria.getProcessDefinitionId())) {
			sb.append("	and d.id_ = #{criteria.processDefinitionId}");
		}
		if(StringUtils.notEmpty(criteria.getProcessDefinitionKey())) {
			sb.append("	and d.key_ = #{criteria.processDefinitionKey}");
		}
		if(StringUtils.notEmpty(criteria.getProcessDefinitionName())) {
			sb.append("	and d.NAME_ like concat('%',#{criteria.processDefinitionName},'%')");
		}
		if(StringUtils.notEmpty(criteria.getProcessInstanceBusinessKey())) {
			sb.append("	and i.BUSINESS_KEY_ = #{criteria.processInstanceBusinessKey}");
		}
		if(StringUtils.notEmpty(criteria.getProcessInstanceId())) {
			sb.append("	and t.proc_inst_id_ = #{processInstanceId}");
		}
		if(StringUtils.notEmpty(criteria.getProcessInstanceStartUser())) {
			sb.append("	and i.START_USER_ID_ = #{criteria.processInstanceStartUser}");
		}
		if(StringUtils.notEmpty(criteria.getProcessInstanceCreateTimeStart())&&
					StringUtils.notEmpty(criteria.getProcessInstanceCreateTimeEnd())) {
			sb.append("	and i.START_TIME_ between #{criteria.processInstanceCreateTimeStart} and #{criteria.processInstanceCreateTimeEnd}");
		}
		if(StringUtils.notEmpty(criteria.getDefinitionKey())) {
			sb.append("	and t.TASK_DEF_KEY_ = #{criteria.definitionKey}");
		}
		if(StringUtils.notEmpty(criteria.getUsername())) {
			if (criteria.isCascadeGroup()) {
				String groups = "select g.ID_ from act_id_group g, act_id_membership membership where g.id_ = membership.group_id_ and membership.user_id_ = '"+criteria.getUsername()+"'";
				sb.append(" AND (T.ASSIGNEE_ = '" + criteria.getUsername()
				+ "' OR (L.TYPE_ = 'candidate' AND L.USER_ID_ = '" + criteria.getUsername() 
				+ "' OR L.GROUP_ID_ IN ("+groups+")) )");
			}else {
				sb.append(" AND (T.ASSIGNEE_ = '" + criteria.getUsername()
				+ "' OR (L.TYPE_ = 'candidate' AND L.USER_ID_ = '" + criteria.getUsername() + "') )");
			}
		}
		return sb.toString();
	}
	
}
